﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BoYuanCore.CoreCodeTemplates.DBMappingRules;


namespace BoYuanCore.CoreCodeTemplates.FineUICore
{
    public class FineUIBase
    {
        /// <summary>
        /// 获取备注信息，没有备注则显示表名称
        /// </summary>
        /// <param name="comment">备注信息</param>
        /// <param name="name">表名称</param>
        /// <returns></returns>
        public static string GetComment(string comment, string name)
        {
            return string.IsNullOrEmpty(comment) ? name : comment;
        }

        public static string GetNamespace2Str(string namespace2Str)
        {
            return namespace2Str.Length == 0 ? string.Empty : namespace2Str + ".";
        }

        /// <summary>
        /// 获取默认值,过滤多余符号
        /// </summary>
        /// <param name="valueStr"></param>
        /// <returns></returns>
        public static string GetDefaultValue(string valueStr)
        {
            return valueStr.Length == 0 ? string.Empty : valueStr.Replace("(", string.Empty).Replace(")", string.Empty);
        }

        #region 获取数据库默认值code

        /// <summary>
        /// 获取数据库默认值code
        /// </summary>
        /// <param name="column">字段相关信息</param>
        /// <param name="dbClass">数据库类型(sqlserver,mysql等)</param>
        /// <returns></returns>
        public static string GetDefaultValueCode(DbColumnInfo column, string dbClass)
        {
            if (string.IsNullOrEmpty(column.DefaultValue)) return string.Empty; //没有默认值返回空字符串

            string defaultValue = column.DefaultValue;

            if (defaultValue.Contains("::"))//去掉 pgsql 默认值格式 ''::character varying
            {
                defaultValue = defaultValue.Split(':')[0];
            }

            switch (column.PropertyName)
            {
                case "bool":
                    return defaultValue
                               .Replace("b", string.Empty)
                               .Replace("(", string.Empty)
                               .Replace(")", string.Empty)
                               .Replace("'", string.Empty)
                           == "0" ? "false" : "true";

                case "datetime": //一般都是默认当前时间函数,例如 sqlserver getdate()
                    return "DateTime.Now";

                //数值相关类型
                case "uint": //break;
                case "long": //break;
                case "byte": //break;
                case "sbyte": //break;
                case "short": //break;
                case "ushort": //break;
                case "enum": //break;
                case "int": //break;
                case "decimal": //break;
                case "ulong": //break;
                case "float": //break;
                case "double":
                    return defaultValue
                        .Replace("(", string.Empty)
                        .Replace(")", string.Empty)
                        .Replace("'", string.Empty);

                case "guid":
                    if (defaultValue.Length < 30) //自动生成新guid。数据库可能是有自定义函数，例如sqlserver newid()
                    {
                        return "Guid.NewGuid()";
                    }
                    else
                    {
                        return "\"" + defaultValue + "\"";
                    }

                case "string":
                    string tempStr = defaultValue;
                    if (defaultValue.Substring(0, 1) == "(" &&
                        defaultValue.Substring(defaultValue.Length - 1) == ")")
                    {
                        //如果开头和结尾是 ( )  去掉，获取默认值
                        tempStr = defaultValue.Substring(1, defaultValue.Length - 2);
                    }

                    if (tempStr == "''")
                    {
                        return "\"\"";
                    }
                    else if (tempStr.Substring(0, 1) == "'" && tempStr.Substring(tempStr.Length - 1) == "'")
                    {
                        //如果开头和结尾是 ' '  去掉，获取默认值
                        tempStr = tempStr.Substring(1, tempStr.Length - 2);
                    }
                    else if (tempStr.Substring(0, 2) == "N'" && tempStr.Substring(tempStr.Length - 1) == "'")
                    {
                        //如果开头和结尾是 N' '  去掉，获取默认值
                        tempStr = tempStr.Substring(2, tempStr.Length - 3);
                    }

                    return "\"" + tempStr + "\"";

                default: //不知道什么类型，返回空字符
                    return string.Empty;
            }
        }


        #endregion


        /// <summary>
        /// 获取控件和实体映射代码
        /// </summary>
        /// <param name="list">字段信息集合</param>
        /// <param name="modelValue">给实体赋值</param>
        /// <param name="updateColumn">update要更新的字段</param>
        /// <param name="insertColumn">insert要赋值的字段</param>
        public static void GetControlMappingCode(List<DbColumnInfo> list, out string modelValue,
            out string updateColumn, out string insertColumn)
        {
            //StringBuilder sb = new StringBuilder();//获取页面加载值
            StringBuilder sb2 = new StringBuilder(); //赋值
            //StringBuilder sb3 = new StringBuilder();//int验证
            StringBuilder sb4 = new StringBuilder(); //update要更新的字段
            StringBuilder sb5 = new StringBuilder(); //insert要赋值的字段

            //bool haveDefaultValue;//是否有默认值
            foreach (var colm in list)
            {
                switch (colm.PropertyName) 
                {
                    case "bool":
                        sb2.AppendLine(string.Format("            mo.{0}=Convert.ToBoolean(fc[\"f_{0}\"]); ",
                            colm.DbColumnNameToClassName));
                        break;

                    case "datetime":
                        if (!string.IsNullOrEmpty(colm.DefaultValue)) //时间类型默认值有值，一般都是当前时间
                        {
                            //有默认值，添加时候需要赋值，更新不需要修改
                            sb5.AppendLine(string.Format("                mo.{0} = DateTime.Now;", colm.DbColumnNameToClassName));
                        }
                        else //没有默认值，需要手动添加
                        {
                            sb2.AppendLine(string.Format(
                                "            " + (colm.IsNullable
                                    ? "if (DateTime.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                    : "mo.{0} = Convert.ToDateTime(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        }

                        break;
                    //长类型
                    case "uint":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (uint.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToUInt32(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;
                    case "long":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (long.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToInt64(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;
                    case "byte":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (byte.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToByte(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;

                    case "sbyte":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (sbyte.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToSByte(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;
                    case "short":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (short.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToInt16(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;
                    case "ushort":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (ushort.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToUInt16(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;
                    case "enum": //break;
                    case "int":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (int.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToInt32(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;
                    case "decimal":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (decimal.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToDecimal(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;
                    case "ulong":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (ulong.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToUInt64(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;

                    case "float":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (float.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToSingle(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;

                    case "double":
                        sb2.AppendLine(string.Format(
                            "            " + (colm.IsNullable
                                ? "if (double.TryParse(fc[\"f_{0}\"], out var {0}TempResult)) mo.{0} = {0}TempResult;"
                                : "mo.{0}= Convert.ToDouble(fc[\"f_{0}\"]);"), colm.DbColumnNameToClassName));
                        break;

                    case "guid": //break;
                    default:
                        sb2.AppendLine(string.Format("            mo.{0}= fc[\"f_{0}\"]; ", colm.DbColumnNameToClassName));
                        break;
                }

                sb4.Append(",p." + colm.DbColumnNameToClassName);
            }

            modelValue = sb2.ToString();
            updateColumn = sb4.ToString();
            insertColumn = sb5.ToString();
        }


        /// <summary>
        /// 获取两个字符串中间的字符串
        /// </summary>
        /// <param name="str">要处理的字符串,例ABCD</param>
        /// <param name="str1">第1个字符串,例AB</param>
        /// <param name="str2">第2个字符串,例D</param>
        /// <param name="isIgnoreCase">是否忽略大小</param>
        /// <returns>例返回C</returns>
        public static string GetBetweenStr(string str, string str1, string str2, bool isIgnoreCase = true)
        {
            int i1 = isIgnoreCase ? str.IndexOf(str1, StringComparison.InvariantCultureIgnoreCase) : str.IndexOf(str1);
            if (i1 < 0) //找不到返回空
            {
                return "";
            }

            int i2 = isIgnoreCase
                ? str.IndexOf(str2, i1 + str1.Length, StringComparison.InvariantCultureIgnoreCase)
                : str.IndexOf(str2, i1 + str1.Length); //从找到的第1个字符串后再去找
            if (i2 < 0) //找不到返回空
            {
                return "";
            }

            return str.Substring(i1 + str1.Length, i2 - i1 - str1.Length);
        }

    }

    

}
